package com.iot.common.security.jwt;

import com.alibaba.fastjson.JSONObject;
import com.iot.common.core.constant.SecurityConstants;
import com.iot.common.security.domain.SimpleUser;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import lombok.extern.slf4j.Slf4j;
import java.text.ParseException;
import java.util.Date;

@Slf4j
public class JWTUtil {

	/**
	 * @methodName：createToken
	 * @description：创建token @editNote：
	 */
	public static String createToken(String payload) throws JOSEException {
		// 创建密钥
		MACSigner macSigner = new MACSigner(SecurityConstants.TOKEN_SECRET);

		// payload
		JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("subject").claim("payload", payload)
				.expirationTime(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRE_TIME)).build();
		JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);

		// 创建签名的JWT
		SignedJWT signedJWT = new SignedJWT(jwsHeader, claimsSet);
		signedJWT.sign(macSigner);

		// 生成token
		String jwtToken = signedJWT.serialize();
		return jwtToken;
	}

	/**
	 * @methodName：verifierToken
	 * @description：验证token
	 */
	public static boolean verifierToken(String headerToken) {
		try {
			SignedJWT jwt = getSignedJWT(headerToken);
			JWSVerifier verifier = new MACVerifier(SecurityConstants.TOKEN_SECRET);
			// 校验是否有效
			if (!jwt.verify(verifier)) {
				log.error("token不合法，检测不过关");
				return false;
			}

			// 校验超时
			Date expirationTime = jwt.getJWTClaimsSet().getExpirationTime();
			if (new Date().after(expirationTime)) {
				log.error("token已经过期");
				return false;
			}
			// 获取载体中的数据
			return true;
		} catch (ParseException | JOSEException e) {
			log.error("token校验出错", e);
		}
		return false;
	}

	public static SignedJWT getSignedJWT(String headerToken) throws ParseException {
		String token = headerToken.replace(SecurityConstants.TOKEN_PREFIX, "");
		log.info("token is {}", token);
		return SignedJWT.parse(token);
	}

	public static SimpleUser getSimpleUser(String headerToken) throws ParseException, JOSEException {
		SignedJWT jwt = getSignedJWT(headerToken);
		Object account = jwt.getJWTClaimsSet().getClaim("payload");
		if (account != null) {
			return JSONObject.parseObject(account.toString(), SimpleUser.class);
		}
		return null;
	}

}
